package se.webbzon.boltzmann.game.object.action;

import java.awt.Color;
import java.nio.ByteBuffer;

import se.webbzon.oschi01.worldeditor.WorldObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public abstract class AbstractActionDeflation extends WorldObjectDeflation {
	
	private boolean hasParent;
	
	private Color color;
	
	private boolean frontOnly;
	
	private double range;
	
	/*============================================================
	Constructors
	============================================================*/

	/** Creates a new empty abstract action deflation. **/
	public AbstractActionDeflation(	int deflationProperties,
									WorldObject[] dependencies) {
		super(deflationProperties, dependencies);
	}
	
	/** Creates a new abstract action deflation with a given
	 * set of deflation properties and dependencies. The proivded
	 * abstract action will be deflated as well. **/
	public AbstractActionDeflation(	int deflationProperties,
									WorldObject[] dependencies,
									AbstractAction action) {
		super(	deflationProperties, 
				mergeDependencies(dependencies,action.getParent()));
		hasParent = action.getParent() != null;
		color = action.getColor();
		frontOnly = action.getFrontOnly();
		range = action.getRange();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the color of this action deflation. **/
	public Color getColor() {
		return color;
	}
	
	/** Returns true if this action deflation only accepts activation
	 * from the front. **/
	public boolean getFrontOnly() {
		return frontOnly;
	}
	
	/** Returns the range of this action deflation. **/
	public double getRange() {
		return range;
	}
	
	/** Returns the parent of this action deflation. **/
	public WorldStaticObject getParent() {
		if (hasParent) {
			int dependencies = super.dependencies();
			return (WorldStaticObject) super.getDependency(dependencies-1);
		} else
			return null;
	}
	
	@Override public int dependencies() {
		if (hasParent)
			return super.dependencies()-1;
		else
			return super.dependencies();
	}
	
	@Override public WorldObject[] getDependencies() {
		if (hasParent) {
			int dependencies = dependencies();
			WorldObject[] dependencyArray = new WorldObject[dependencies];
			for (int i = 0; i < dependencies; i++)
				dependencyArray[i] = getDependency(i);
			return dependencyArray;
		} else
			return super.getDependencies();
	}
	
	@Override public void inflate(ByteBuffer buff) {
		// Read from buffer
		hasParent = buff.get() != 0;
		final int red, green, blue, alpha;
		red = 0x000000FF & buff.get();
		green = 0x000000FF & buff.get();
		blue = 0x000000FF & buff.get();
		alpha = 0x000000FF & buff.get();
		color = new Color(red,green,blue,alpha);
		frontOnly = buff.get() != 0;
		range = buff.getDouble();
	}

	@Override public ByteBuffer deflate(int allocate) {
		ByteBuffer buff = ByteBuffer.allocate(allocate + 14);
		
		// Write to buffer
		buff.put(hasParent ? (byte) 1 : (byte) 0);
		buff.put((byte) color.getRed());
		buff.put((byte) color.getGreen());
		buff.put((byte) color.getBlue());
		buff.put((byte) color.getAlpha());
		buff.put(frontOnly ? (byte) 1 : (byte) 0);
		buff.putDouble(range);
		
		return buff;
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Merges the dependencies of the provided dependency array with
	 * the parent of the abstract action. **/
	private final static WorldObject[] mergeDependencies(	WorldObject[] dependencies,
															WorldStaticObject parent) {
		if (parent == null)
			return dependencies;
		else {
			int size = dependencies.length;
			WorldObject[] mergedDependencies = new WorldObject[size+1];
			System.arraycopy(dependencies, 0, mergedDependencies, 0, size);
			mergedDependencies[size] = parent;
			return mergedDependencies;
		}
	}

}
